package com.task.controller;


import com.task.common.annotation.Log;
import com.task.common.enums.BusinessType;
import com.task.common.util.body.CommonModel;
import com.task.common.util.body.JsonResult;
import com.task.common.util.body.ResultTool;
import com.task.common.util.string.StringUtils;
import com.task.entity.Chunk;
import com.task.entity.QingShuFile;
import com.task.service.ChunkService;
import com.task.service.IFileService;
import com.task.util.ChunkResult;
import com.task.util.ServletUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.OutputStream;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author Huzz
 * @since 2021-10-11
 */
@Api(tags = "文件上传")
@RestController
@RequestMapping("/sys/file")
public class FileController {

    @Resource
    private IFileService fileService;

    @Autowired
    private ChunkService chunkService;

    @Log(title = "文件传输-小文件上传", businessType = BusinessType.UPLOAD)
    @ApiOperation(value = "小文件上传")
    @PostMapping("/uploadFile")
    public JsonResult uploadFile(MultipartFile file) {
        return fileService.upload(file);
    }

    /**
     * 分片上传
     * 实现大文件传输, 断点续传
     * ---------------------------------------------------------------------------------------------
     */
    @Log(title = "文件上传:校验文件", isSaveResponseParam = true, businessType = BusinessType.CHECK)
    @ApiOperation(value = "校验文件")
    @GetMapping("/chunkUpload")
    public ChunkResult checkChunk(Chunk chunk, HttpServletResponse response) {
        return chunkService.checkChunkState(chunk, response);
    }

    @Log(title = "文件上传:分片上传", isSaveResponseParam = true, businessType = BusinessType.UPLOAD)
    @ApiOperation(value = "分片上传")
    @PostMapping("/chunkUpload")
    public Integer uploadChunk(Chunk chunk) {
        return chunkService.uploadFile(chunk);
    }

    @Log(title = "文件上传:文件合并", isSaveResponseParam = true, businessType = BusinessType.OTHER)
    @ApiOperation(value = "文件合并")
    @PostMapping("/mergeFile")
    public CommonModel mergeFile(@RequestBody QingShuFile sysFile) {
        return fileService.mergeFile(sysFile);
    }

    @Log(title = "文件上传:查询文件列表", isSaveRequestParam = true, businessType = BusinessType.SELECT)
    @ApiOperation(value = "查询文件列表")
    @GetMapping(value = "/selectFileList")
    public JsonResult selectFileList(@RequestParam(defaultValue = "1", required = false) Integer pageNum,
                                     @RequestParam(defaultValue = "10", required = false) Integer pageSize,
                                     QingShuFile sysFile) {
        return ResultTool.success(fileService.selectFileList(sysFile, pageNum, pageSize));
    }

    @Log(title = "文件上传:文件删除", isSaveResponseParam = true, businessType = BusinessType.DELETE)
    @ApiOperation(value = "文件删除")
    @DeleteMapping(value = "/deleteFile")
    public JsonResult deleteFile(@RequestBody QingShuFile sysFile) {
        if (StringUtils.isNull(sysFile) || StringUtils.isNull(sysFile.getId())) {
            return ResultTool.fail("文件id不能为空");
        }
        return fileService.deleteFile(sysFile) ? ResultTool.success() : ResultTool.fail();
    }

    @Log(title = "文件上传:下载", businessType = BusinessType.DOWNLOAD)
    @ApiOperation(value = "文件下载")
    @GetMapping(value = "/download")
    public void download(@RequestBody QingShuFile sysFile,
                         HttpServletRequest req,
                         HttpServletResponse resp) {
        String filePath = sysFile.getPath();
        String fileName = sysFile.getFileName();
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        OutputStream fos = null;
        try {
            bis = new BufferedInputStream(new FileInputStream(filePath));
            fos = resp.getOutputStream();
            bos = new BufferedOutputStream(fos);
            ServletUtils.setFileDownloadHeader(req, resp, fileName);
            int byteRead = 0;
            byte[] buffer = new byte[8192];
            while ((byteRead = bis.read(buffer, 0, 8192)) != -1) {
                bos.write(buffer, 0, byteRead);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                bos.flush();
                bis.close();
                fos.close();
                bos.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    @Log(title = "文件下载: 访问服务器资源")
    @GetMapping("/accessResourceAgent/fileId/{id}")
    public JsonResult accessResourceAgent(@PathVariable("id") Integer fileId) {
        String path = fileService.getFilePath(fileId);
        if (!path.isEmpty()) {
            return ResultTool.success(path);
        }
        return ResultTool.fail();
    }

}
